/*
 * This file is part of the Marmalade SDK Code Samples.
 *
 * (C) 2001-2012 Marmalade. All Rights Reserved.
 *
 * This source code is intended only as a supplement to the Marmalade SDK.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 */

//-----------------------------------------------------------------------------
// ExampleIwUIDailyReports
//-----------------------------------------------------------------------------

/**
 * @page ExampleIwUIDailyReports IwUI DailyReports Example
 *
 * @include IwUIHelloWorld.cpp
 */

// Standard includes
#include "IwUIDailyReport.h"

// Standard includes

#include "IwUI.h"
//#include "s3eContacts.h"

#include "s3eFile.h"



// Static data
static CIwUIDailyReport* s_App;
// String names of languages
#define RESTYPE_LOCALISED_STRING    "CLocalisedString"
//Declare function
bool SetButtonImages(CIwUIButton* pButton, const char* pTextureResName);
const char* LocaliseCallback(const CIwPropertySet& propertySet);
//-----------------------------------------------------------------------------
enum LocaliseLanguages
	{
		LOCALISE_ENGLISH,
		LOCALISE_FRENCH,

		NUM_LANGUAGES,

		DEFAULT_LANGUAGE = LOCALISE_ENGLISH
	};

// Current language
	LocaliseLanguages g_Localise = DEFAULT_LANGUAGE;

const char* g_LanguageNames[] =
{
    "english",
    "vietnamese"
};


class  CLocalisedString : public CIwResource
{

public:
    IW_MANAGED_DECLARE(CLocalisedString);

    CLocalisedString()
    {
		
    }

    ~CLocalisedString()
    {
    }

    // IwResource virtuals
    virtual bool ParseAttribute(CIwTextParserITX* pParser, const char* pAttrName)
    {
        for (int i=0; i<NUM_LANGUAGES; i++)
        {
            if (!stricmp(g_LanguageNames[i], pAttrName))
            {
                pParser->ReadString(m_Strings[i]);
                return true;
            }
        }

        return CIwResource::ParseAttribute(pParser, pAttrName);
    }

    virtual void ParseClose(CIwTextParserITX* pParser)
    {
        CIwManaged* pParent = pParser->GetObject(-1);
        if (CIwResGroup* pResGroup = dynamic_cast<CIwResGroup*>(pParent))
        {
            // Add ourselves to the current res group.
            pResGroup->AddRes(RESTYPE_LOCALISED_STRING, this);
        }
        else
        {
            CIwResource::ParseClose(pParser);
        }
    }

    virtual void Serialise()
    {
        CIwResource::Serialise();

        for (int i=0; i<NUM_LANGUAGES; i++)
        {
            m_Strings[i].Serialise();
        }
    }

    // Public interface
    const char* GetString(LocaliseLanguages language)
    {
        if ((0 <= language) && (language < NUM_LANGUAGES))
        {
            return m_Strings[language].c_str();
        }

        return NULL;
    }

private:
    // Member data
    CIwStringL m_Strings[2];
};
IW_MANAGED_IMPLEMENT_FACTORY(CLocalisedString);

class CController : public CIwUIController
{
public:
    CController()
    {
        IW_UI_CREATE_VIEW_SLOT1(this, "CController", CController, OnClickQuit,
            CIwUIElement*)
        IW_UI_CREATE_VIEW_SLOT2(this, "CController", CController, OnRadioLanguage,
            CIwUIElement* , int16 )
    }

private:

    void OnRadioLanguage(CIwUIElement*, int16 mode)
    {
        if (mode >= 0 && mode < NUM_LANGUAGES)
        {
            g_Localise = (LocaliseLanguages) mode;
        }
    }

    void OnClickQuit(CIwUIElement* pCommandElement)
    {
		GetApp()->DoneTask(pCommandElement);
        s3eDeviceRequestQuit();
    }
};


int main()
{
    CIwUIDailyReport app;
    app.Run();
    return 0;
}

//-----------------------------------------------------------------------------

CIwUIDailyReport* GetApp()
{
    IwAssertMsg(UI, s_App, ("Accessing NULL app singleton"));

    return s_App;
}

CIwUIDailyReport::CIwUIDailyReport() :
    m_DailyReports(NULL),
    m_CreateDialog(NULL),
    m_DeleteDialog(NULL),
    m_EditRowId(-1),
    m_DeleteRowId(-1),
    m_ItemSource(NULL)
{
    // Set singleton
    IwAssert(UI, !s_App);
    s_App = this;

    // Initialise the IwUI module
    IwUIInit();

    // Register class factories
    IW_CLASS_REGISTER(CDailyReportsViewHandler);
    IW_CLASS_REGISTER(CDailyReportsItemSource);
    IW_CLASS_REGISTER(CCreateDailyReportHandler);
    IW_CLASS_REGISTER(CDeleteDailyReportHandler);
	IW_CLASS_REGISTER(CLocalisedString);
	//IwUISetLocaliseCallback(LocaliseCallback);

    // Instantiate singletons.
	new CIwUIView;
	new CController;
    //new CIwUIController;

    new CIwUITextInput;
}

CIwUIDailyReport::~CIwUIDailyReport()
{
	DoneTask(NULL);
    // Destroy singletons.
    delete IwGetUITextInput();
    delete IwGetUIController();
    delete IwGetUIView();

    // Remove class factories
    IW_CLASS_REMOVE(CDailyReportsViewHandler);
    IW_CLASS_REMOVE(CDailyReportsItemSource);
    IW_CLASS_REMOVE(CCreateDailyReportHandler);
    IW_CLASS_REMOVE(CDeleteDailyReportHandler);
	IW_CLASS_REMOVE(CLocalisedString);
    // Terminate the IwUI module
    IwUITerminate();

    // Clear singleton
    IwAssert(UI, s_App == this);
    s_App = NULL;
}

uint64 lastUpdate = s3eTimerGetMs();
// Public interface
void CIwUIDailyReport::Run()
{
    Init();

    uint64 lastTime = s3eTimerGetMs();
	lastUpdate = lastTime;
    while (!s3eDeviceCheckQuitRequest())
    {
        // Calculate an update time step.
        uint64 currentTime = s3eTimerGetMs();
        int32 updateTime = currentTime > lastTime ?
            MIN((int32)(currentTime - lastTime), 1000) : 0;
        lastTime = currentTime;

		//updateTime = 1000;
		//s3eDeviceYield(updateTime);
        // Update & render UI
        Update(updateTime);
        Render();

        // Standard device interaction
        s3eDeviceYield();
        s3eKeyboardUpdate();
        s3ePointerUpdate();
    }
}

void CIwUIDailyReport::SetActiveItemSource(IDailyReportsItemSource* pItemSource)
{
    IwAssert(UI, !pItemSource || !m_ItemSource);

    m_ItemSource = pItemSource;
}

void CIwUIDailyReport::UpdateAllDailyReports()
{
    //m_ItemSource->UpdateAllUIDs();
}

void CIwUIDailyReport::ShowCreateDialog(int32 editUID)
{
    m_EditRowId = editUID;

    m_CreateDialog->SetVisible(true);
    IwGetUIView()->SetModal(m_CreateDialog);
}

void CIwUIDailyReport::GetInitialDailyReport(DailyReportField& taskName, DailyReportField& beginDate,
    DailyReportField& startTime, DailyReportField& endTime, DailyReportField& describe) const
{
        taskName[0] = '\0';
        startTime[0] = '\0';
        endTime[0] = '\0';
		describe[0] = '\0';
   if (m_EditRowId == -1)
    {
    }
    else
    {
		m_ItemSource->GetDataById(m_EditRowId, taskName, beginDate, startTime, endTime, describe);
		//SqlStatement select = dbProvider->sqlQuery("select RowId, TaskName, BeginDate, StartTime, EndTime, Description from DailyReport where RowId=?");
		//select.bind(m_EditRowId);
		//select.execute();
		//if(!select.hasRow())
		//return;
		//do
		//{
		//	const SqlStatement::ResultRow& row = select.currentRow();
		//	strcpy(taskName, row.getStringField("TaskName"));
		//	strcpy(beginDate, row.getStringField("BeginDate"));
		//	strcpy(startTime, row.getStringField("StartTime"));
		//	strcpy(endTime, row.getStringField("EndTime"));
		//	strcpy(describe, row.getStringField("Description"));
		//}while(select.nextRow());
		//select.destroy();
		
	}
        /*GetField(m_EditRowId, S3E_DAILYREPORT_FIELD_TASK_NAME, taskName);
		GetField(m_EditRowId, S3E_DAILYREPORT_FIELD_BEGIN_DATE, beginDate);
        GetField(m_EditRowId, S3E_DAILYREPORT_FIELD_START_TIME, taskName);
		GetField(m_EditRowId, S3E_DAILYREPORT_FIELD_END_TIME, endTime);
		GetField(m_EditRowId, S3E_DAILYREPORT_FIELD_DESCRIBE, describe);*/
}

void CIwUIDailyReport::CreateConfirmed(const char* pTaskName,
    const char* pBeginDate, const char* pStartTime, const char* pEndTime, const char* pDescribe)
{
    // Either editing existing, or create new dailyReport
    bool editingExisting = m_EditRowId != -1;

    if (editingExisting)
    {
		m_ItemSource->UpdateItemByRowId(m_EditRowId, pTaskName, pBeginDate, pStartTime, pEndTime, pDescribe);
    }
    else
    {
        //m_ItemSource->CreateItem();
        //IwAssertMsg(UI, false, ("Failed to create dailyReport"));
    }

    m_EditRowId = -1;
}

void CIwUIDailyReport::HideCreateDialog()
{
    IwGetUIView()->SetModal(NULL);
    m_CreateDialog->SetVisible(false);
}

void CIwUIDailyReport::ShowDeleteDialog(int32 pRowId)
{
    // Get RowId of dailyReport we want to delete
	//int32 rowId = pRowId;// m_ItemSource->GetUID(dailyReportIndex);
    IwAssertMsg(UI, pRowId != -1, ("Trying to delete invalid dailyReport index"));

    if (pRowId != -1)
    {
        // Store RowId we're trying to delete
        m_DeleteRowId = pRowId;

        // Show delete dailyReport dialog
        m_DeleteDialog->SetVisible(true);
        IwGetUIView()->SetModal(m_DeleteDialog);
    }
}

void CIwUIDailyReport::DeleteConfirmed()
{
    IwAssertMsg(UI, m_DeleteRowId != -1, ("Never showed delete dialog"));

    ////s3eResult result = s3eDailyReportsDelete(m_DeleteRowId);
    ////IwAssertMsg(UI, result == S3E_RESULT_SUCCESS, ("Failed to delete dailyReport"));

    // Tell table view to remove dailyReport
    m_ItemSource->DeleteItemByRowId(m_DeleteRowId);

    m_DeleteRowId = -1;
}

void CIwUIDailyReport::HideDeleteDialog()
{
    IwGetUIView()->SetModal(NULL);
    m_DeleteDialog->SetVisible(false);
}




// ---------------------------------- VNThanh ----------------------------------

#include "time.h"
// Get now
time_t GetNow()
{
    //Get local time
    time_t curtime;
    struct tm *loctime;
    curtime = time (NULL);
    loctime = localtime (&curtime);
    return mktime(loctime);
}
// Show current Date
char* GetDate(time_t pLocalTime)
{
	char* date = new char[64];
    strftime (date, 64, "%d-%m-%Y", localtime(&pLocalTime));
	return date;
}
// Get current Time
char* GetTime(time_t pLocalTime)
{
	char* time = new char[64];
    strftime (time, 64, "%H:%M:%S", localtime(&pLocalTime));
	return time;
}

// Insert Task
void CIwUIDailyReport::CreateTask(CIwUIElement* pCommandElement)
{
	// Call DoneTask
	DoneTask(pCommandElement);

	// Get Ourner Button
	CIwUIButton* cmd = (CIwUIButton*)pCommandElement;
	CLocalisedString* pLocString = (CLocalisedString*)IwGetResManager()->GetResHashed(cmd->m_Hash, RESTYPE_LOCALISED_STRING, IW_RES_SEARCH_ALL_F);
	const char* locStr = pLocString->GetString(g_Localise);
	char* taskName = new char[255];
	strcpy(taskName,locStr);


//char str[100];
//sprintf(str, locStr, "name");
//delete str;
	


	const time_t now = GetNow();
	char* beginDate = GetDate(now);
	char* startTime = GetTime(now);
	char* endTime = new char[20];
	strcpy(endTime, "");
	int duration = 0;
	
	m_EditRowId = m_ItemSource->CreateItem(taskName, beginDate, startTime, endTime, duration);
	delete taskName;
	delete beginDate;
	delete startTime;
	delete endTime;
}
// Done Task
void CIwUIDailyReport::DoneTask(CIwUIElement* pCommandElement)
{
	//if(m_EditRowId != -1)
	{
		const time_t now = GetNow();
		char* endDate = GetDate(now);
		char* endTime = GetTime(now);

		m_ItemSource->UpdateDoneByRowId(m_EditRowId, endDate, endTime);
		//m_EditRowId = -1;

		delete endDate;
		delete endTime;
	}
}
// ---------------------------------- End VNThanh ----------------------------------




// Private interface
void CIwUIDailyReport::Init()
{

	IwUISetLocaliseCallback(LocaliseCallback);
	
	//new CController;
    // Load the hello world UI
    IwGetResManager()->LoadGroup("IwUIDailyReport.group");
	
    // Set the default style sheet
    IwGetUIStyleManager()->SetStylesheet("iwui");

	 CIwGxFont* font = (CIwGxFont*)IwGetResManager()->GetResNamed("arial14", "CIwGxFont");
    IwGxFontSetFont(font);
	

    // Create soft-keyboard and ensure appears on top.
    IwGetUITextInput()->CreateSoftKeyboard();
    IwGetUIView()->GetChildNamed("soft_keyboard")->SetRenderSlot(INT32_MAX-1);
	
    // Clone UI elements
    m_DailyReports = CIwUIElement::CreateFromResource("DailyReports");

	//CIwUIButton* bt = (CIwUIButton*) m_DailyReports->GetChildNamed("Delete");
	//SetButtonImages(bt, "en_language");

    m_CreateDialog = CIwUIElement::CreateFromResource("CreateDialog");
    m_DeleteDialog = CIwUIElement::CreateFromResource("DeleteDialog");

    // Set initial visibility
    m_CreateDialog->SetVisible(false);
    m_DeleteDialog->SetVisible(false);

    // Add into view
    IwGetUIView()->AddElementToLayout(m_DailyReports);
    IwGetUIView()->AddElementToLayout(m_CreateDialog);
    IwGetUIView()->AddElementToLayout(m_DeleteDialog);

    // Choose initial focus
    IwGetUIView()->ChooseFocus(m_DailyReports);
}

void CIwUIDailyReport::Update(int32 deltaMS)
{
	static LocaliseLanguages g_OldLocalise = DEFAULT_LANGUAGE;
    if (g_OldLocalise != g_Localise)
    {
        g_OldLocalise = g_Localise;
        IwGetUIView()->Reactivate();
    }
	uint64 currentTime = s3eTimerGetMs();
	int32 updateTime = currentTime > lastUpdate ?
	MIN((int32)(currentTime - lastUpdate), 1000) : 0;
	if(updateTime == 1000)
	{
		m_ItemSource->UpdateDurationByRowId(1);
		lastUpdate = currentTime;
	}
    // Update the controller (this will generate control events etc.)
    IwGetUIController()->Update();

    // Update the view (this will do animations etc.)
    IwGetUIView()->Update(deltaMS);
}

void CIwUIDailyReport::Render()
{
    // Clear surface
    IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F);

    // Render the UI
    IwGetUIView()->Render();

    // Flush IwGx
    IwGxFlush();

    // Display the rendered frame
    IwGxSwapBuffers();
}


bool SetButtonImages(CIwUIButton* pButton, const char* pTextureResName)
{
    // Find texture in resource manager
    CIwTexture* pTexture = IwSafeCast<CIwTexture*>(
        IwGetResManager()->GetResNamed(pTextureResName, IW_GX_RESTYPE_TEXTURE));
    IwAssertMsg(UI, pTexture, ("Cannot change button textures to %s as not loaded",
        pTextureResName));

    if (!pTexture)
    {
        return false;
    }
   
    // Set texture on buttonUp and buttonDown styles of button
    IwUISetPropertyOnInlineStyle(pButton, "buttonUp", "texture", pTexture);
    IwUISetPropertyOnInlineStyle(pButton, "buttonDown", "texture", pTexture);

    // Usually buttonUp and buttonDown are 'border' type drawables. We want a simple image.
    IwUISetPropertyOnInlineStyle(pButton, "buttonUp", "drawableType", IwHashString("image"));
    IwUISetPropertyOnInlineStyle(pButton, "buttonDown", "drawableType", IwHashString("image"));

    return true;
}

const char* LocaliseCallback(const CIwPropertySet& propertySet)
{
    uint32 hash = 0;
    if (propertySet.GetProperty("localiseCaption", hash, true))
    {
        CLocalisedString* pLocString = (CLocalisedString*)
            IwGetResManager()->GetResHashed(hash,
                RESTYPE_LOCALISED_STRING, IW_RES_SEARCH_ALL_F);

        if (pLocString)
        {
            return pLocString->GetString(g_Localise);
        }
    }
    return NULL;
}